home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swags_z.zip / STRINGS.SWG / 0077_Speedy Strings.pas < prev    next >
Pascal/Delphi Source File  |  1994-05-25  |  5KB  |  160 lines

  1. {
  2. DJ>Can anyone please help me speed up the following functions?
  3.  
  4.   Aha! A challange! <g>
  5.  
  6. DJ>I wouldn't mind using built-in assembly either!
  7.  
  8.   You can still achieve a large increase in speed without using
  9.   assembly code. Here's my stab at rewriting your routines.
  10.   (These could be written faster still, but I'll leave that up
  11.   to you.)
  12. }
  13.  
  14. {$A+,B-,D-,E-,F-,G-,I-,L-,N-,O-,P-,Q-,R-,S+,T-,V-,X-}
  15. {$M 4096,0,655360}
  16.  
  17. program Test_New_Tab_Functions;
  18.  
  19.   (***** Remove space-wasting chars from end of line.                 *)
  20.   (*                                                                  *)
  21.   function TrimRight2({input }
  22.                          st_IN : string) :
  23.                       {output}
  24.                          string;
  25.   var
  26.     by_Index : byte;
  27.   begin
  28.     by_Index := length(st_IN);
  29.     while st_IN[by_Index] IN [#0,#9,#32] do
  30.       begin
  31.         dec(by_Index);
  32.         dec(st_IN[0])
  33.       end;
  34.     TrimRight2 := st_IN
  35.   end;        (* TrimRight2.                                          *)
  36.  
  37.   (***** Replace tabs with 8 spaces.                                  *)
  38.   (*                                                                  *)
  39.   function DeTab2({input }
  40.                      st_IN : string) :
  41.                   {output}
  42.                      string;
  43.   var
  44.     by_Index1,
  45.     by_Index2 : byte;
  46.     st_Temp   : string;
  47.   begin
  48.     by_Index2 := 0;
  49.     fillchar(st_Temp[1], 255, #32);
  50.     for by_Index1 := 1 to length(st_IN) do
  51.       if (st_IN[by_Index1] <> #9) then
  52.         begin
  53.           inc(by_Index2);
  54.           st_Temp[by_Index2] := st_IN[by_Index1]
  55.         end
  56.       else
  57.         by_Index2 := succ(by_Index2 shr 3) shl 3;
  58.     st_Temp[0] := chr(by_Index2);
  59.     DeTab2 := st_Temp
  60.   end;        (* DeTab2.                                              *)
  61.  
  62.   (***** Replace spaces with tabs to compress string.                 *)
  63.   (*                                                                  *)
  64.   function EnTab2({input }
  65.                      st_IN : string) :
  66.                   {output}
  67.                      string;
  68.   var
  69.     by_Count,
  70.     by_IndexIN,
  71.     by_IndexOUT : byte;
  72.     st_Temp     : string;
  73.   begin
  74.     by_IndexIN  := 0;
  75.     by_IndexOUT := 0;
  76.     by_Count    := 0;
  77.     st_Temp[0]  := #0;
  78.     fillchar(st_Temp[1], length(st_IN), #32);
  79.     repeat
  80.       inc(by_IndexIN);
  81.       if (st_IN[by_IndexIN] <> #32) then
  82.         begin
  83.           inc(by_IndexOUT);
  84.           st_Temp[by_IndexOUT] := st_IN[by_IndexIN]
  85.         end
  86.       else
  87.         begin
  88.           by_Count := 0;
  89.           while ((by_IndexIN + by_Count) < length(st_IN))
  90.           AND   (st_IN[(by_IndexIN + by_Count)] = #32)
  91.           AND   (((by_IndexIN + by_Count) mod 8) <> 0) do
  92.             inc(by_Count);
  93.  
  94.           if (by_Count > 0) then
  95.             begin
  96.               if (((by_IndexIN + by_Count) mod 8) = 0) then
  97.                 begin
  98.                   inc(by_IndexOUT);
  99.                   st_Temp[by_IndexOUT] := #9;
  100.                   inc(by_IndexIN, by_Count)
  101.                 end
  102.               else
  103.                 begin
  104.                   inc(by_IndexOUT, by_Count);
  105.                   inc(by_IndexIN,  pred(by_Count))
  106.                 end
  107.             end
  108.           else
  109.             inc(by_IndexOUT)
  110.         end
  111.     until (by_IndexIN = length(st_IN));
  112.     st_Temp[0] := chr(by_IndexOut);
  113.     EnTab2 := st_Temp
  114.   end;        (* EnTab2.                                              *)
  115.  
  116. var
  117.   by_Loop  : byte;
  118.   st_Temp1,
  119.   st_Temp2 : string;
  120.  
  121. BEGIN
  122.   st_Temp1[0] := chr(245);
  123.   fillchar(st_Temp1[1], 245, 'A');
  124.   st_Temp1 := st_Temp1 + #9#0#32#32#9#9#9#0#32#0;
  125.  
  126.   st_Temp2 := TrimRight2(st_Temp1);
  127.  
  128.   st_Temp1 := '';
  129.   for by_Loop := 1 to 17 do
  130.     st_Temp1 := st_Temp1 + 'ABCDEFG' + #9;
  131.  
  132.   st_Temp2 := DeTab2(st_Temp1);
  133.  
  134.   st_Temp1 := '';
  135.   for by_Loop := 1 to 25 do
  136.     st_Temp1 := st_Temp1 + 'ABCDE     ';
  137.  
  138.   st_Temp2 := EnTab2(st_Temp1)
  139. END.
  140.  
  141.   Benchmarking my new routines against your old routines on my
  142.   386DX-40 running Novell DOS 7.0, the results are:
  143.  
  144.     Old TrimRight Time = 1.034 ms
  145.     New TrimRight Time = 0.126 ms (820 percent faster)
  146.  
  147.     Old DeTab Time     = 2.514 ms
  148.     New DeTab Time     = 0.391 ms (640 percent faster)
  149.  
  150.     Old EnTab Time     = 8.450 ms
  151.     New EnTab Time     = 1.004 ms (840 percent faster)
  152.  
  153.   ...Two things to keep in mind when trying to optimize a routine
  154.   are:
  155.         Always try to reduce the number of loops your routine
  156.         has to make.
  157.  
  158.         Copy/Move your data as little as possible.
  159.  
  160.